/*
 * @Author: lineCode 1145938682@qq.com
 * @Date: 2025-03-15 22:10:00
 * @LastEditors: lineCode 1145938682@qq.com
 * @LastEditTime: 2025-03-19 19:13:12
 * @FilePath: /backend/shorthand-modules/shorthand-modules-content/src/main/java/com/angus/modules/content/service/impl/PayPalServiceImpl.java
 */
package com.angus.modules.content.service.impl;

import com.angus.common.core.web.domain.AjaxResult;
import com.angus.common.security.config.PayPalConfig;
import com.angus.common.security.utils.SecurityUtils;
import com.angus.api.content.domain.OrderCommission;
import com.angus.modules.content.domain.SysOrder;
import com.angus.modules.content.dto.PayPalOrderPayDto;
import com.angus.modules.content.repository.OrderCommissionRepository;
import com.angus.modules.content.repository.SysOrderRepository;
import com.angus.modules.content.service.PayPalService;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.paypal.api.payments.*;
import com.paypal.base.rest.PayPalRESTException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author liyanan
 * @date 2025/03/07 10:16 PM
 * @description
 */
@Service
public class PayPalServiceImpl implements PayPalService {

    @Resource
    private PayPalConfig payPalConfig;

    @Resource
    private SysOrderRepository sysOrderRepository;

    @Resource
    private OrderCommissionRepository orderCommissionRepository;

    public AjaxResult payPalPay(PayPalOrderPayDto dto) {
        Long userId = SecurityUtils.getUserId();
        try {
            SysOrder order = sysOrderRepository.getOrderByOrderNo(dto.getOrderNo(), userId);
            if(Objects.isNull(order)){
                return AjaxResult.error("订单不存在");
            }
            // 创建支付请求
            Payment payment = this.createPayment(
                    order.getOrderNo(),
                    order.getCourseAmount(),
                    dto.getCurrency(),
                    "PayPal",
                    "sale",
                    order.getCourseName()
            );
            // 提取审批链接
            String approvalLink = payment.getLinks().stream()
                    .filter(link -> "approval_url".equals(link.getRel()))
                    .findFirst()
                    .orElseThrow(() -> new RuntimeException("审批链接不存在")).getHref();

            return AjaxResult.success(Collections.singletonMap("redirectUrl", approvalLink));
        } catch (PayPalRESTException e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 创建 PayPal 支付订单
     * @param orderNo     订单编号
     * @param total       支付金额
     * @param currency    货币类型（如 USD）
     * @param method      支付方式（如 paypal）
     * @param intent      支付意图（如 sale）
     * @param description 商品描述
     * @return 创建的支付对象
     * @throws PayPalRESTException
     */
    public Payment createPayment(String orderNo, BigDecimal total, String currency, String method,
                                 String intent, String description) throws PayPalRESTException {
        // 1. 设置金额
        Amount amount = new Amount();
        amount.setCurrency(currency);
        amount.setTotal(String.format("%.2f", total)); // 金额格式化为两位小数

        // 2. 设置交易信息
        Transaction transaction = new Transaction();
        transaction.setDescription(description);  // 交易描述
        transaction.setAmount(amount); // 交易金额
        transaction.setCustom(orderNo); // 关联订单号
        List<Transaction> transactions = new ArrayList<>();
        transactions.add(transaction);

        // 3. 构建支付对象
        Payer payer = new Payer();
        payer.setPaymentMethod(method);

        // 4. 设置重定向 URL
        RedirectUrls redirectUrls = new RedirectUrls();
        redirectUrls.setCancelUrl(payPalConfig.getCancelUrl());
        redirectUrls.setReturnUrl(payPalConfig.getSuccessUrl());

        // 5. 构建 Payment 对象
        Payment payment = new Payment();
        payment.setIntent(intent); // 支付意图（sale: 即时支付）
        payment.setPayer(payer);   // 设置资金渠道
        payment.setTransactions(transactions);  // 设置交易信息
        payment.setRedirectUrls(redirectUrls);  // 设置重定向

        // 5. 创建支付请求
        return payment.create(payPalConfig.apiContext());
    }

    /**
     * 执行支付操作（用户完成 PayPal 页面操作后调用）
     */
    public Payment executePayment(String paymentId, String payerId) throws PayPalRESTException {
        Payment payment = new Payment();
        payment.setId(paymentId);
        PaymentExecution paymentExecute = new PaymentExecution();
        paymentExecute.setPayerId(payerId);
        return payment.execute(payPalConfig.apiContext(), paymentExecute);
    }

    /**
     * 处理 PayPal 支付成功回调
     * @param paymentId
     * @param payerId
     * @return
     */
    public AjaxResult paymentSuccess(String paymentId, String payerId) {
        try {
            Payment payment = executePayment(paymentId, payerId);
            if ("approved".equals(payment.getState())) {
                // 处理支付成功逻辑，如更新订单状态、生成交易记录等
                String orderNo = payment.getTransactions().get(0).getCustom();
                SysOrder order = sysOrderRepository.getOrder(orderNo);
                if(Objects.nonNull(order)){
                    // 更新订单状态
                    sysOrderRepository.updateOrderStatus(orderNo, order.getValidDays());
                    if (StringUtils.isNotBlank(order.getRecommendCode())){
                        //生成要转账佣金记录
                        OrderCommission orderCommission = new OrderCommission();
                        orderCommission.setOrderNo(orderNo);
                        orderCommission.setUserId(order.getUserId());
                        orderCommission.setCourseCode(order.getCourseCode());
                        orderCommission.setCourseAmount(order.getCourseAmount());
                        orderCommission.setRecommendCode(order.getRecommendCode());
                        orderCommission.setCommissionRate(order.getCommissionRate());
                        orderCommission.setCommissionAmount(order.getCourseAmount().multiply(order.getCommissionRate()));
                        orderCommissionRepository.save(orderCommission);
                    }
                }
                return AjaxResult.success("支付成功");
            }
        } catch (PayPalRESTException e) {
            return AjaxResult.error("支付执行失败: " + e.getMessage());
        }
        return AjaxResult.error("支付未完成或失败");
    }

    /**
     * 处理 PayPal 支付取消回调
     * @param paymentId
     * @param payerId
     * @return
     */
    public AjaxResult paymentCancel(String paymentId, String payerId) {
        try {
            Payment payment = executePayment(paymentId, payerId);
            if (!"approved".equals(payment.getState())) {
                // 处理支付成功逻辑，如更新订单状态、生成交易记录等
                String orderNo = payment.getTransactions().get(0).getCustom();
                sysOrderRepository.updateOrderCancelStatus(orderNo);
                return AjaxResult.success("支付取消");
            }
        } catch (PayPalRESTException e) {
            return AjaxResult.error("支付取消失败: " + e.getMessage());
        }
        return AjaxResult.error("支付取消失败");
    }

    /**
     * 验证 PayPal Webhook 事件的签名
     * （此处为示例，实际应使用 PayPal 提供的 HMAC-SHA256 验证方法）
     */
    public boolean validateWebhook(String body, String signature) {
        // 实际开发中应使用 PayPal 提供的工具类验证签名
        return true; // 示例返回 true
    }
}
